package com.myblog.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.myblog.constant.CodeType;
import com.myblog.constant.RedisHashKey;
import com.myblog.constant.RedisKey;
import com.myblog.mapper.ArticleMapper;
import com.myblog.mapper.TagMapper;
import com.myblog.model.Article;
import com.myblog.model.Tag;
import com.myblog.model.Visitor;
import com.myblog.service.ArticleService;
import com.myblog.utils.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;


import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class ArticleServiceImpl implements ArticleService {

    private static final String ARTICLE_URL = "article/";

    @Autowired
    private ArticleMapper articleMapper;

    @Autowired
    private TagMapper tagMapper;

    @Autowired
    private RedisServiceImpl redisServiceImpl;


    /**
     * 发布博客功能
     * @param article
     * @param username
     * @return
     */
    @Override
    @Transactional
    public DataMap publicArticle(Article article,String username) {

        //通过文章的id判断是修改文章还是新增文章
        TimeUtil timeUtil = new TimeUtil();
        String formatDateForThree = timeUtil.getFormatDateForThree();
        //如果文章id不等于null，为修改
        if (article.getId() != null && !StringUtil.BLANK.equals(article.getId())){

            //重设更新时间
            article.setUpdateDate(formatDateForThree);
            Article beforeArticle = articleMapper.selectArticleById(article.getId());
            //同步之前的属性值
            //设置之前的articleId
            article.setArticleId(beforeArticle.getArticleId());
            //设置之前的发布时间publishData
            article.setPublishDate(beforeArticle.getPublishDate());
            //设置之前的点赞数
            article.setLikes(beforeArticle.getLikes());
            //设置之前的上一篇文章id
            article.setLastArticleId(beforeArticle.getLastArticleId());
            //设置之前的下一篇文章id
            article.setNextArticleId(beforeArticle.getNextArticleId());

            //作者 originalAuthor
            if (username == null){
                article.setAuthor("匿名");
                if (article.getArticleType().equals("原创")){
                    article.setOriginalAuthor(username);
                }
            }
            else {
                article.setAuthor(username);
                if (article.getArticleType().equals("原创")){
                    article.setOriginalAuthor(username);

                }
            }

            articleMapper.updataArticleById(article);
        }
        //id为空，新增博客
        else {

            //作者 originalAuthor
            if (username == null){
                article.setAuthor("匿名");
                if (article.getArticleType().equals("原创")){
                    article.setOriginalAuthor(username);
                }
            }
            else {
                article.setAuthor(username);
                if (article.getArticleType().equals("原创")){
                    article.setOriginalAuthor(username);
                }
            }

            article.setPublishDate(formatDateForThree);
            article.setUpdateDate(formatDateForThree);
            //文章id
            long articleId = timeUtil.getLongTime();
            article.setArticleId(articleId);

            //文章url articleUrl
            article.setArticleUrl("http://localhost:8080/article/" + article.getArticleId());

            //点赞数likes默认为0
            article.setLikes(0);
            //上一篇文章Id
            long lastArticleId = articleMapper.selectLastArticleId();
            article.setLastArticleId(lastArticleId);
            article.setNextArticleId(0);

            articleMapper.addArticle(article);
            //设置上一篇文章的nextArticle属性
            articleMapper.updataNextArticleId(lastArticleId,article.getArticleId());
        }

        JSONObject resultJSON = new JSONObject();
        resultJSON.put("articleTitle",article.getArticleTitle());
        resultJSON.put("updateDate",article.getUpdateDate());
        resultJSON.put("author",article.getAuthor());
        resultJSON.put("articleUrl","/article/"+article.getArticleId());

        redisServiceImpl.updateNumOfAllArticleNum(articleMapper.selectNumOfArticle()+1);

        return DataMap.success().setData(resultJSON);
    }

    /**
     * 后台文章管理页面分页获取文章
     * @param rows
     * @param pageNum
     * @return
     */
    @Override
    public DataMap getArticleByPage(Integer rows, Integer pageNum) {

        PageHelper.startPage(pageNum,rows);
        List<Article> articles = articleMapper.selectAllArticle();
        PageInfo<Article> pageInfo = new PageInfo<>(articles);
        JSONArray jsonArray = new JSONArray();
        for (Article article : articles) {
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("id",article.getId());
            jsonObject.put("articleId",article.getArticleId());
            jsonObject.put("articleTitle",article.getArticleTitle());
            jsonObject.put("publishDate",article.getPublishDate());
            jsonObject.put("articleCategories",article.getArticleCategories());
            //获取文章浏览量
            //查询redis中的文章浏览量pageName为 article/articleId
            Object articleVisitorNum = redisServiceImpl.getHash(StringUtil.VISITOR,ARTICLE_URL+Long.toString(article.getArticleId()));
            //如果查询不到，则从速句酷中查询
            Visitor visitor = redisServiceImpl.visitorMsgIfExist(articleVisitorNum, ARTICLE_URL + Long.toString(article.getArticleId()));
            jsonObject.put("visitorNum",visitor.getVisitorNum());// 文章浏览量
            jsonArray.add(jsonObject);
        }
        JSONObject result = new JSONObject();
        result.put("result",jsonArray);

        JSONObject pageJson = new JSONObject();
        pageJson.put("pageNum",pageInfo.getPageNum());
        pageJson.put("pageSize",pageInfo.getSize());
        pageJson.put("total",pageInfo.getTotal());
        pageJson.put("pages",pageInfo.getPages());
        pageJson.put("isFirstPage",pageInfo.isIsFirstPage());
        pageJson.put("isLastPage",pageInfo.isIsLastPage());

        result.put("pageInfo",pageJson);
        return DataMap.success().setData(result);
    }


    /**
     * 通过删除按钮获取id，删除文章，并设置前后内容
     * @param id
     * @return
     */
    @Override
    @Transactional
    public DataMap deleteArticleById(Integer id) {
        long lastArticleId = articleMapper.getLastArticleIdById(id);
        long nextArticleId = articleMapper.getNextArticleIdById(id);

        //更新上一篇文章中的下一篇文章id，定位到本文章的下一篇文章
        articleMapper.updataNextArticleId(lastArticleId,nextArticleId);
        //更新下一篇文章中的上一篇文章id，定位到本文章的上一篇文章
        articleMapper.updataLastArticleId(nextArticleId,lastArticleId);
        //删除
        articleMapper.deleteArticleById(id);
        return DataMap.success();
    }


    /**
     * 编辑文章重新发布时候获取草稿
     * @param id
     * @return
     */
    @Override
    @Transactional
    public DataMap getDraftArticleById(Integer id) {
        //获取文章等级，即tagSize
        Article article = articleMapper.selectArticleById(id);

        String[] tags = StringAndArray.stringToArray(article.getArticleTags().substring(0,article.getArticleTags().length()));
        Tag tag = tagMapper.selectByTagName(tags[0]);


        JSONObject result = new JSONObject();
        result.put("id",article.getId());
        result.put("articleTitle",article.getArticleTitle());
        result.put("articleContent",article.getArticleContent());
        result.put("articleType",article.getArticleType());
        result.put("articleGrade",tag.getTagSize());
        result.put("originalAuthor",article.getOriginalAuthor());
        result.put("articleUrl",article.getArticleUrl());
        result.put("articleCategories",article.getArticleCategories());
        result.put("articleTags",tags);

        return DataMap.success().setData(result);
    }

    @Override
    public Article getArticleById(Integer id) {

        return articleMapper.selectArticleById(id);
    }

    /**
     * 主页分页获取文章列表
     * @param rows
     * @param pageNum
     * @return
     */
    @Override
    public DataMap getArticleByPageIndex(Integer rows, Integer pageNum) {
        PageHelper.startPage(pageNum,rows);
        List<Article> articles = articleMapper.selectAllArticle();
        PageInfo<Article> pageInfo = new PageInfo<>(articles);
        List<JSONObject> result = new ArrayList<>();
        for (Article article : articles) {
            JSONObject jsonObject = new JSONObject();

            jsonObject.put("id",article.getId());
            jsonObject.put("articleCategories",article.getArticleCategories());
            jsonObject.put("articleTabloid",article.getArticleTabloid());
            jsonObject.put("articleTags",StringAndArray.stringToArray(article.getArticleTags()));
            jsonObject.put("articleTitle",article.getArticleTitle());
            jsonObject.put("articleType",article.getArticleType());
            jsonObject.put("likes",article.getLikes());
            jsonObject.put("originalAuthor",article.getOriginalAuthor());
            jsonObject.put("publishDate",article.getPublishDate());
            jsonObject.put("thisArticleUrl","/article/"+article.getArticleId());
            result.add(jsonObject);
        }

        JSONObject pageJson = new JSONObject();
        pageJson.put("pageNum",pageInfo.getPageNum());
        pageJson.put("pageSize",pageInfo.getSize());
        pageJson.put("total",pageInfo.getTotal());
        pageJson.put("pages",pageInfo.getPages());
        pageJson.put("isFirstPage",pageInfo.isIsFirstPage());
        pageJson.put("isLastPage",pageInfo.isIsLastPage());

        result.add(pageJson);

        return DataMap.success().setData(result);
    }

    /**
     * 通过文正id获取文章
     * @param articleId
     * @return
     */
    @Override
    public Map<String, String> findArticleTitleByArticleId(long articleId) {
        Article article = articleMapper.selectArticleByArticleId(articleId);
        Map<String,String> articleMsg = new HashMap<>();
        if(article != null) {
            articleMsg.put("articleTitle", article.getArticleTitle());
            articleMsg.put("articleTabloid", article.getArticleTabloid());
        }
        return articleMsg;
    }

    /**
     * 通过文章id获取文章，然后从redis中获取点赞信息，同时更新文章点赞信息
     * @param articleId
     * @return
     */
    @Override
    public DataMap getArticleByArticleId(long articleId,Integer isLiked) {
        Article article = articleMapper.selectArticleByArticleId(articleId);
        //从redis中读取点赞likes信息
        Object articleLikeNum = redisServiceImpl.getHash(RedisKey.ARTICLE,Long.toString(articleId));
        Integer NumOfArticleLike = redisServiceImpl.numOfArticleLikeByIdIfExist(articleLikeNum,articleId);
        article.setLikes(NumOfArticleLike);
        article.setIsLiked(isLiked);
        return DataMap.success().setData(article);
    }

    @Override
    public DataMap getSearchArticleByPageIndex(Integer rows, Integer pageNum, String context) {
        PageHelper.startPage(pageNum,rows);
        String newContent = "%"+context+"%";
        List<Article> articles = articleMapper.selectArticleByTitle(newContent);
//        List<Article> articles2 = articleMapper.selectArticleByContext(newContent);
//        articles.addAll(articles2);
        PageInfo<Article> pageInfo = new PageInfo<>(articles);
        List<JSONObject> result = new ArrayList<>();
        for (Article article : articles) {
            JSONObject jsonObject = new JSONObject();

            jsonObject.put("id",article.getId());
            jsonObject.put("articleCategories",article.getArticleCategories());
            jsonObject.put("articleTabloid",article.getArticleTabloid());
            jsonObject.put("articleTags",StringAndArray.stringToArray(article.getArticleTags()));
            jsonObject.put("articleTitle",article.getArticleTitle());
            jsonObject.put("articleType",article.getArticleType());
            jsonObject.put("likes",article.getLikes());
            jsonObject.put("originalAuthor",article.getOriginalAuthor());
            jsonObject.put("publishDate",article.getPublishDate());
            jsonObject.put("thisArticleUrl","/article/"+article.getArticleId());
            result.add(jsonObject);
        }

        JSONObject pageJson = new JSONObject();
        pageJson.put("pageNum",pageInfo.getPageNum());
        pageJson.put("pageSize",pageInfo.getSize());
        pageJson.put("total",pageInfo.getTotal());
        pageJson.put("pages",pageInfo.getPages());
        pageJson.put("isFirstPage",pageInfo.isIsFirstPage());
        pageJson.put("isLastPage",pageInfo.isIsLastPage());

        result.add(pageJson);

        return DataMap.success().setData(result);
    }


}
